#include "array.h"
#include "sparse.h"

vector::vector(int l, const Array<int>& ai, const Array<real>& av){
    int i;
    len=av.size();
    buf=new vector::entry[len];
    for(i=0; i<len; i++){
        buf[i].ind=ai[i];
        buf[i].val=av[i];
    }
    label=l;
}

vector::vector(){
    label=0;
    buf=0;
    len=0;
}

vector::vector(const vector& v):buf(new vector::entry[v.len]),len(v.len){
    for(int i=0; i<len; i++)
        buf[i] = v.buf[i];
}

vector& vector::operator=(const vector& v){
    if(this == &v)
        return *this;
    delete[] buf;
    len = v.len;
    buf = new vector::entry[len];
    for(int i=0; i<len; i++)
        buf[i] = v.buf[i];
    return *this;
}

vector::~vector(){
    delete[] buf;
}


void vector::update(const vector* x){
    int i,j,n,y;
    vector::entry* tmp=new vector::entry[len+x->len];
    y=x->label;
    for(n=i=j=0; i<len && j<x->len;){
        if(buf[i].ind < x->buf[j].ind)
            tmp[n++]=buf[i++];
        else if(buf[i].ind > x->buf[j].ind){
            tmp[n]=x->buf[j++];
            tmp[n++].val*=y;
        }
        else{
            tmp[n]=buf[i++];
            tmp[n++].val+=y*x->buf[j++].val;
        }
    }
    while(i<len){
        tmp[n++]=buf[i++];
    }
    while(j<x->len){
        tmp[n]=x->buf[j++];
        tmp[n++].val*=y;
    }
    delete[] buf;
    buf=tmp;
    len=n;
}

void vector::at(int i, int& ind, real& val)const{
    ind=buf[i].ind;
    val=buf[i].val;
}

real vector::dot(const vector& v)const{
    real sum=0.0;
    vector::entry* p=buf;
    vector::entry* q=v.buf;
    while(p<buf+len && q<v.buf+v.len){
        int diff = p->ind - q->ind;
        if(diff>0)
            q++;
        else if (diff<0)
            p++;
        else
            sum+=(p++)->val * (q++)->val;
    }
    return sum;
}

const int vector::getClass()const{
    return label;
}
const int vector::size()const{
    return len;
}
